﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Input;


namespace PonGun
{
    public class Bullet : Base2DObject
    {
        public Base2DObject Parent { get; set; }

        public bool Fired { get; set; }

        public float MuzzleVelocity { get; set; }

        public ObjectCallBack OnBulletDied;

        public Bullet(Game1 game, Base2DObject parent, string asset = "Textures/bullet", float muzzleVelocity = 8)
            : base(game)
        {
            Parent = parent;

            Width = 8;
            Height = 4;

            Asset = asset;

            MuzzleVelocity = muzzleVelocity;
            Friction = 0;

            RegisteredCollider = true;
        }

        public void Shoot(Vector2 velocity)
        {
            Position = Parent.Position + velocity;
            Fired = true;
            Velocity = velocity;
        }

        public override void Update(GameTime gameTime)
        {
            if (Fired)
            {
                if (Position.X < minPosition.X || Position.X > maxPosition.X || Position.Y < minPosition.Y || Position.Y > maxPosition.Y)
                    KillBullet(new CollisionData(this, null));
                else
                    base.Update(gameTime);
            }
        }

        void KillBullet(CollisionData collisionData)
        {
            Fired = false;

            base.OnCollided(collisionData);

            // Take me out of the collision engine

            collisionManager.UnRegister(this, false);

            if (OnBulletDied != null)
                OnBulletDied(this);
        }

        public override void Collided(CollisionData collisionData)
        {
            Base2DObject collidedWith = null;
            if (collisionData.Objects[0] == this)
                collidedWith = (Base2DObject)collisionData.Objects[1];
            else
                collidedWith = (Base2DObject)collisionData.Objects[0];

            int score = 0;
            string msg = string.Empty;

            if (collidedWith is Pickup)
            {
                score = 500 * Game.Level;

                KillBullet(collisionData);
                ParticleStrikeEffect(-collidedWith.GetCollisionNormal(this), collidedWith.Color);

            }

            if (collidedWith is Ball)
            {
                score = 250 * Game.Level;
                KillBullet(collisionData);
                ParticleStrikeEffect(collidedWith.GetCollisionNormal(this), collidedWith.Color);
            }

            if (collidedWith is Bullet)
            {
                
                score = 500 * Game.Level;
                msg = string.Format("+{0} Bullet Hit!", score);
                

                KillBullet(collisionData);
                ((Bullet)collidedWith).KillBullet(collisionData);
                ParticleStrikeEffect(-collidedWith.GetCollisionNormal(this), collidedWith.Color);
            }

            if (collidedWith is Bat)
            {
                if (((Bat)collidedWith).Erroded(this, true))
                {
                    Game.Content.Load<SoundEffect>("Audio/SFX/cityHit").Play();
                    // Damage the player..
                    switch (((Bat)collidedWith).Player)
                    {
                        case PlayerIndex.One:
                            KillBullet(collisionData);
                            break;
                        case PlayerIndex.Two:
                            KillBullet(collisionData);
                            break;
                    }

                    score = 10 * Game.Level;
                    msg = string.Format("+{0} Bat Hit!", score);
                    ParticleStrikeEffect(collidedWith.GetCollisionNormal(this), collidedWith.Color);
                }
            }

            if (collidedWith is Block)
            {
                if (((Block)collidedWith).Erroded(this, true))
                {
                    Game.Content.Load<SoundEffect>("Audio/SFX/bhbt").Play();
                    score = 1 * Game.Level;
                    KillBullet(collisionData);
                    ParticleStrikeEffect(collidedWith.GetCollisionNormal(this), collidedWith.Color);
                }
            }

            if (collidedWith is City)
            {
                if (((City)collidedWith).Erroded(this, true))
                {
                    Game.Content.Load<SoundEffect>("Audio/SFX/cityHit").Play();
                    score = 100 * Game.Level;
                    KillBullet(collisionData);
                    ParticleStrikeEffect(collidedWith.GetCollisionNormal(this), collidedWith.Color);
                }
            }

            if (score != 0)
                Game.Bats.SingleOrDefault(entity => entity.Player == ((BatGun)Parent).Bat.Player).Score +=score;

            if (msg != string.Empty)
                Game.ShowPopUpMessage(new PopMsg() { message = msg, Color = Color.White, position = Position });

            if (!Fired)
                base.Collided(collisionData);

        }
        public void ParticleStrikeEffect(Vector2 normal, Color color)
        {
            Vector2 orgNorm = normal;
            TimeSpan lifetime = new TimeSpan(0, 0, 0, 0, 100);
            float fadeSpeed = .1f;

            Vector2 velMul = Vector2.One * MathHelper.Lerp(4, 8, (float)Game1.rnd.NextDouble());
            Game.testEmitter.AddParticle(new Particle(Game) { Position = Position, Velocity = normal * velMul, Spin = -.1f, LifeSpan = lifetime, FadeSpeed = fadeSpeed, Color = color });

            if (orgNorm.X == 0)
                normal.X -= .25f;

            if (orgNorm.Y == 0)
                normal.Y -= .25f;

            velMul = Vector2.One * MathHelper.Lerp(4, 8, (float)Game1.rnd.NextDouble());
            Game.testEmitter.AddParticle(new Particle(Game) { Position = Position, Velocity = normal * velMul, Spin = -.1f, LifeSpan = lifetime, FadeSpeed = fadeSpeed, Color = color });

            if (orgNorm.X == 0)
                normal.X -= .25f;

            if (orgNorm.Y == 0)
                normal.Y -= .25f;

            velMul = Vector2.One * MathHelper.Lerp(4, 8, (float)Game1.rnd.NextDouble());
            Game.testEmitter.AddParticle(new Particle(Game) { Position = Position, Velocity = normal * velMul, Spin = -.1f, LifeSpan = lifetime, FadeSpeed = fadeSpeed, Color = color });

            if (orgNorm.X == 0)
                normal.X += 1.25f;

            if (orgNorm.Y == 0)
                normal.Y += 1.25f;

            velMul = Vector2.One * MathHelper.Lerp(4, 8, (float)Game1.rnd.NextDouble());
            Game.testEmitter.AddParticle(new Particle(Game) { Position = Position, Velocity = normal * velMul, Spin = -.1f, LifeSpan = lifetime, FadeSpeed = fadeSpeed, Color = color });

            if (orgNorm.X == 0)
                normal.X += .25f;

            if (orgNorm.Y == 0)
                normal.Y += .25f;

            velMul = Vector2.One * MathHelper.Lerp(4, 8, (float)Game1.rnd.NextDouble());
            Game.testEmitter.AddParticle(new Particle(Game) { Position = Position, Velocity = normal * velMul, Spin = -.1f, LifeSpan = lifetime, FadeSpeed = fadeSpeed, Color = color });
        }
    }
}
